package com.example.sql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.example.sql.handle.ResultSetHandle;

/**
 * mysql数据库操作工具类
 */
public class MysqlDbHelper {
    /**
     * 用户名
     */
    private static final String USERNAME = "root";
    /**
     * 用户密码
     */
    private static final String PASSWORD = "root";
    /**
     * 数据库链接
     */
    private static final String URL = "jdbc:mysql://localhost:3306/RUNOOB?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai";
    /**
     * 驱动包
     */
    private static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
    /**
     * 优先加载数据库驱动
     */
    {
        try {
            Class.forName(JDBC_DRIVER);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 获取数据库链接
     */
    private static Connection getConnection() {
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }

    /**
     * 执行新增，更新，删除操作
     * <li>新增：新增时只需将sql参数换为insert语句
     * <li>更新：更新时只需将sql参数换为update语句
     * <li>删除：删除时只需将sql参数换为delete语句
     * 
     * @param sql     具体sql语句
     * @param objects 参数数据与sql中的占位符（？）一一对应
     * @return 受影响的行数
     * @throws SQLException 需处理一个sql异常
     */
    public static int executUpdate(String sql, Object... objects) throws SQLException {
        // 获取链接
        Connection connection = getConnection();
        // 预处理sql
        PreparedStatement statement = connection.prepareStatement(sql);
        // 处理参数值
        for (int i = 0; i < objects.length; i++) {
            // i+1意为参数从1开始
            statement.setObject(i + 1, objects[i]);

        }
        // 执行更新操作
        int result = statement.executeUpdate();
        return result;

    }

    /**
     * 执行sql查询操作
     * @param <T> 对象类型，如：User对应user表，RunoobTbl对应runoob_tbl表
     * @param sql 具体的sql查询语句，如：select * from users where username=?；
     * @param resultSetHandle 查询所得结果的结果集处理接口，需要具体的实现类，如：UserHandle.java
     * @param objects 参数数据与sql中的占位符（？）一一对应
     * @return 返回泛型T的List<T>列表，若无结果，返回new ArrayList<>();
     * @throws SQLException 需处理一个sql异常
     */
    public static <T> List<T> executeQuery(String sql, ResultSetHandle<T> resultSetHandle, Object... objects)
            throws SQLException {
        // 获取链接
        Connection connection = getConnection();
        // 预处理sql
        PreparedStatement statement = connection.prepareStatement(sql);
        // 处理参数
        for (int i = 0; i < objects.length; i++) {
            statement.setObject(i + 1, objects[i]);
        }
        // 执行查询
        ResultSet resultSet = statement.executeQuery();
        // 处理结果
        List<T> resultList = new ArrayList<>();
        while (resultSet.next()) {
            T handleResult = resultSetHandle.handle(resultSet);
            resultList.add(handleResult);
        }
        return resultList;
    }
}
